package com.tianji.remark.service.impl;

import com.tianji.api.dto.remark.LikedTimesDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.utils.*;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.remark.domain.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.tianji.common.constants.MqConstants.Exchange.LIKE_RECORD_EXCHANGE;

/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-03-26
 */
@Slf4j
@Service
@Primary
@RequiredArgsConstructor
public class RedisLikedRecordServiceImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {

    private final RabbitMqHelper rabbitMqHelper;
    private final StringRedisTemplate redisTemplate;
    private final String likeSetBiz = "likes:set:biz:";

    /**
     * 查询所有业务对应的点赞数
     * @param ids
     * @return
     */
    @Override
    public List<LikedTimesDTO> getByIds(List<Long> ids) {
        List<LikedTimesDTO> ans = new ArrayList<>();
        for (Long id : ids) {
            LikedTimesDTO likedTimesDTO = new LikedTimesDTO();
            likedTimesDTO.setBizId(id);
            String key = likeSetBiz + id;
            Integer size = redisTemplate.opsForSet().members(key).size();
            likedTimesDTO.setLikedTimes(size);
            ans.add(likedTimesDTO);
        }
        return ans;
    }

    /**
     * 添加点赞
     * @param likeRecordFormDTO
     */
    @Override
    public void addLike(LikeRecordFormDTO likeRecordFormDTO) {

        boolean isSuccess = likeRecordFormDTO.getLiked() ? like(likeRecordFormDTO) : unlike(likeRecordFormDTO);

        if (!isSuccess) {
            return;
        }

        Long total = redisTemplate.opsForSet().size(likeSetBiz + likeRecordFormDTO.getBizId());

        if (ObjectUtils.isEmpty(total)) {
            return;
        }

        redisTemplate.opsForZSet().add(
                "likes:bizType:" + likeRecordFormDTO.getBizType()
                , likeRecordFormDTO.getBizId().toString()
                , total
        );
    }

    private boolean unlike(LikeRecordFormDTO likeRecordFormDTO) {
        String key = likeSetBiz + likeRecordFormDTO.getBizId();

        Long result = redisTemplate.opsForSet().remove(key, UserContext.getUser().toString());

        return ObjectUtils.isNotEmpty(result) && result > 0;
    }

    private boolean like(LikeRecordFormDTO likeRecordFormDTO) {
        String key = likeSetBiz + likeRecordFormDTO.getBizId();

        Long result = redisTemplate.opsForSet().add(key, UserContext.getUser().toString());

        return ObjectUtils.isNotEmpty(result) && result > 0;
    }

    @Override
    public Map<Long, Boolean> isLiked(List<Long> ids) {
        Map<Long, Boolean> mp = new HashMap<>();
        for (Long id : ids) {
            String key = likeSetBiz + id;
            if (redisTemplate.opsForSet().isMember(key, String.valueOf(UserContext.getUser()))) {
                mp.put(id, true);
            }
        }
        return mp;
    }

    @Override
    public void readLikeTimesAndSendMessage() {
        // 1. 从redis中读取点赞数，通过元组的方式读取到值和点赞数
        List<LikedTimesDTO> likedTimesDTOs = new ArrayList<>();
        redisTemplate.opsForZSet().rangeWithScores("likes:bizType:QA", 0, -1).forEach(v -> {
            // 1.1 通过元组的方式，将点赞数发送到mq
            likedTimesDTOs.add(LikedTimesDTO.of(Long.parseLong(v.getValue()), v.getScore().intValue()));
        });
        // 2. 通过元组的方式，将点赞数发送到mq
        rabbitMqHelper.sendAsyn(LIKE_RECORD_EXCHANGE, "reply", likedTimesDTOs);

    }
}
